(function (angular) {
    'use strict';
    var httpModule = angular.module("fs.http");
    httpModule.config(httpConfig);
    httpModule.run(initHttpTransform);

    httpConfig.$inject = ['$httpProvider', '$resourceProvider', 'ajaxServiceFactoryProvider'];
    function httpConfig($httpProvider, $resourceProvider, ajaxServiceFactoryProvider) {
        $resourceProvider.stripTrailingSlashes = false;
        $httpProvider.interceptors.push('httpInterceptor');
        $httpProvider.useApplyAsync(true);
        $httpProvider.defaults.withCredentials = true;
        //ajaxServiceFactoryProvider.setBaseUrl('');
    }

    initHttpTransform.$inject = ['$http', '$filter', 'formatService', 'storageService'];
    function initHttpTransform($http, $filter, formatService, storageService) {
        // $http.defaults.paramSerializer = 'httpParamSerializer';
        $http.defaults.transformRequest.unshift(formatRequestDate);
        $http.defaults.transformResponse.push(parseResponseDate);

        function formatRequestDate(requestData) {
            var formatter = storageService.getFormatInfo().longTimestamp;
            function formatDate(requestData) {
                angular.forEach(requestData, function (value, key) {
                    // key fieldCtrl may be cause circle error
                    if (!requestData.hasOwnProperty(key) || 'ruleInfos' == key || 'rules' == key || 'fieldCtrl' == key)
                        return;
                    if (angular.isDate(value)) {
                        requestData[key] = $filter('date')(value, formatter);//formatService.formatDate(value, 'longTimestamp');
                    } else if (angular.isObject(value)) {
                        formatDate(value);
                    }
                });
            }
            if (!formatter) {
                return requestData;
            }
            if (angular.isObject(requestData) && !isFile(requestData) && !isBlob(requestData) && !isFormData(requestData)) {
                formatDate(requestData);
            }
            return requestData;
        }

        function parseResponseDate(responseData, headers, status) {
            var formatter, fsDatePattern;
            function parse(responseData) {
                angular.forEach(responseData, function (value, key) {
                    if (!responseData.hasOwnProperty(key))
                        return;
                    if (angular.isString(value) && fsDatePattern.test(value)) {
                        responseData[key] = formatService.parseDate(value, formatter);
                    } else if (angular.isObject(value)) {
                        parse(value);
                    }
                });
            }
            if (!angular.isObject(responseData) || isFile(responseData) || isBlob(responseData) || isFormData(responseData)) {
                return responseData;
            }
            formatter = storageService.getFormatInfo().longTimestamp;
            if (status != 200 || !formatter) {
                return responseData;
            }
            fsDatePattern = new RegExp(formatter.replace('.', '\\.').replace(/[ydhHMmsS]/g, '\\d').replace(/Z/g, '[-+]\\d{4}'));
            parse(responseData);
            return responseData;
        }

        function isFile(obj) {
            try {
                return toString.call(obj) === '[object File]';
            } catch (e) {
                return false;
            }
        }

        function isFormData(obj) {
            try {
                return toString.call(obj) === '[object FormData]';
            } catch (e) {
                return false;
            }
        }

        function isBlob(obj) {
            try {
                return toString.call(obj) === '[object Blob]';
            } catch (e) {
                return false;
            }
        }
    }
})(angular);